package com.guoranhao.tool.utils;


import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Description:分组方法, 修饰器
 * Copyright (c) Department of Research and Development/Beijing
 * All Rights Reserved.
 * @version 1.0 2017年10月30日 上午9:58 by 宫珣（gongxun@cloud-young.cpm）创建
 */

public interface GroupUtil<T> {

    Logger logger = LoggerFactory.getLogger(GroupUtil.class);

    /**
     * Description:抽象函数自己实现业务逻辑
     * Version1.0 2017/10/30 上午9:59 by 宫珣（gongxun@cloud-young.com/）创建
     * @throws Exception Exception
     */
    Integer execute(List<T> list) throws Exception;

    /**
     * Description:  插入、更新修饰方法，避免一次批量插入数据量过大(多次插入, 外层需加事务)
     * Version1.0 2017/10/30 上午10:16 by 宫珣（gongxun@cloud-young.com/）创建
     * <pre>
     *     subList包含头不包含尾，比如取 subList(0, 2) ，实际上取出的是下标0，1两个元素
     * </pre>
     * @param list          list
     * @param sliceLimit    多少条分成一组
     * @return  成功失败
     * @throws Exception    RuntimeException
     */
    default Boolean divide(List<T> list, Integer sliceLimit) throws Exception {
        int size = list.size();
        int part = ((size % sliceLimit) != 0) ? (size / sliceLimit) + 1 : (size / sliceLimit);
        LogUtil.info(logger, "size is : {0}, part is : {1}, sliceLimit is : {2}", size, part, sliceLimit);
        for (int i = 0; i < part; i++) {
            int fromIndex = i * sliceLimit;
            int toIndex = (sliceLimit * (i + 1)) > size ? size : (sliceLimit * (i + 1));
            List<T> sliceList = list.subList(fromIndex, toIndex);
            if (CollectionUtils.isEmpty(sliceList)) {
                continue;
            }
            Integer num = this.execute(sliceList);
            if (!num.equals(sliceList.size())) {
                throw new RuntimeException(String.format("execute batch error List size  = {%s}, addNum = {%s}", sliceList.size(), num));
            }
        }
        return true;
    }

}
